package com.authine.cloudpivot.ext.controller;

import com.authine.cloudpivot.engine.api.facade.BizObjectFacade;
import com.authine.cloudpivot.engine.api.model.organization.DepartmentModel;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.*;
import com.authine.cloudpivot.engine.component.query.api.Page;
import com.authine.cloudpivot.engine.component.query.api.helper.PageableImpl;
import com.authine.cloudpivot.engine.enums.type.UnitType;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.curator.shaded.com.google.common.collect.Maps;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Api(value = "custom 接口", tags = "")
@RequestMapping("/huatai/custom")
@RestController
@Slf4j
public class CustomController extends BaseController {


    /**
     *  获取 审批规则参与者表达式
     * @param bizId  业务数据id
     * @param activityEnabledField  活动节点 在 规则 里的编码
     * @param activityParticipantField 规则表达式
     * @return
     */
    @RequestMapping("getActivityParticipant")
    public Object getActivityParticipant(String bizId,String activityEnabledField,String activityParticipantField){
        log.info("获取规则开始:bizId={},activityEnabledField={},activityParticipantField={}",bizId,activityEnabledField,activityParticipantField);
        BizObjectFacade bizObjectFacade = super.getBizObjectFacade();
        //获取业务数据
        BizObjectCreatedModel bizObject = bizObjectFacade.getBizObject("fukuan", bizId);

        if (bizObject == null) {
            log.info("业务对象获取失败");
        }

        // TODO: 获取到满足表单实例的规则对象
        BizObjectModel bizRule = this.getBizRule(bizObject);
        // 如果没有找到匹配的规则条件，则直接返回为空对象
        if(bizRule == null){
            return "";
        }
        // TODO:获取这个节点配置是否需要经过
        String activityEnabled = (String) bizRule.get(activityEnabledField);

        if("否".equals(activityEnabled)){
            return "";
        }
        String inUser = (String) bizRule.get(activityParticipantField);
        if (StringUtils.isBlank(inUser)) {
            inUser = "";
        }
        return inUser;
    }


    /**
     *  获取审批规则
     * @param biz
     * @return
     */
    private BizObjectModel getBizRule(BizObjectModel biz){
        log.info("进入获取路由");
        //获取所有 审批规则
        BizObjectQueryModel query = new BizObjectQueryModel();
        query.setSchemaCode("ApproveRule");
        query.setPageable(new PageableImpl(0,Integer.MAX_VALUE));

        Page<BizObjectModel> bizObjectModelPage = super.getBizObjectFacade().queryBizObjectSkipQuery(query);
        List<? extends BizObjectModel> content = bizObjectModelPage.getContent();

        log.info("路由规则size={}", content.size());

        List<? extends BizObjectModel> collect = content.stream().filter(obj -> {

            // 判断路由条件是否满足
            if (isMatchRouteExpress(obj, biz)) {
                return true;
            }
            return false;
        }).sorted((obj, obj1) -> {
            // 判断规则优先级，优先级越小则优先，例如同时有2个规则满足该表单实例，则返回规则优先级最小的
            int ruleIndex0 = Optional.of((BigDecimal) obj.get("RuleIndex")).orElse(BigDecimal.ZERO).intValue();
            int ruleIndex1 = Optional.of((BigDecimal) obj1.get("RuleIndex")).orElse(BigDecimal.ZERO).intValue();
            return ruleIndex0 < ruleIndex1 ? -1 : 1;
        }).collect(Collectors.toList());

        // 返回第一个
        if (collect != null && collect.size() > 0) {
            return collect.get(0);
        }

        return  null;
    }
    // 表单规则路由匹配条件判断
    private boolean isMatchRouteExpress(BizObjectModel routebiz,BizObjectModel biz){
        log.info("表单规则路由匹配条件判断:\n");
        //付款条件
        boolean payConditionResult = false;//付款匹配结果
        String routeExpress = (String) routebiz.get("PayCondition");
        log.info("付款条件:{}",routeExpress);
        if(StringUtils.isNotBlank(routeExpress)){
            String [] strs = null;
            boolean isText = false;//是否文本
            String validateRule = null;
            if(routeExpress.contains("==")){
                //文本类
                strs = routeExpress.split("==");
                isText = true;
            }else{
                //数值类
                if(routeExpress.split(">=").length > 1){
                    strs = routeExpress.split(">=");
                    validateRule = ">=";
                }else if(routeExpress.split(">").length > 1){
                    strs = routeExpress.split(">");
                    validateRule = ">";
                }else if(routeExpress.split("<=").length > 1){
                    strs = routeExpress.split("<=");
                    validateRule = "<=";
                }else if(routeExpress.split("<").length > 1){
                    strs = routeExpress.split("<");
                    validateRule = "<";
                }else if(routeExpress.split("=").length > 1){
                    strs = routeExpress.split("=");
                    validateRule = "=";
                }
            }
            String field = strs[0];
            String value = strs[1];

            if(field.contains(".")){
                //子表
                payConditionResult = judgeBudgetSubject(biz, field.split(".")[0], field.split(".")[1], value, isText, validateRule);
            }else {
                //主表
                payConditionResult = getMatchResult(field, value, isText, biz, validateRule);
            }
        }else {
            //付款情况为空，匹配规则为true
            payConditionResult = true;
        }

        boolean orgScopeResult = false;//组织范围结果

        // 发起人是否属于指定部门或等于指定人
        List<SelectionValue> createrList = (List<SelectionValue>) biz.get("creater");
        SelectionValue creater = createrList.get(0);

        List<SelectionValue> routeUnitList = (List<SelectionValue>) routebiz.get("OrgScope");

        //判断指定人
        for (SelectionValue obj: routeUnitList ) {
            UnitType type = obj.getType();
            // 申请人所属组织 是 用户
            if (type == UnitType.USER) {
                if (obj.getId() != null && obj.getId().equals(creater.getId())) {
                    orgScopeResult = true;
                }
            }
        }
        if(unitContainUnit(routeUnitList,creater)){
            log.info("路由匹配条件:发起人属于指定部门或指定人");
            orgScopeResult = true;
        }
        return orgScopeResult && payConditionResult;
    }

    private boolean getMatchResult(String field, String value, boolean isText, BizObjectModel biz, String validateRule){
        if(isText){
            if(value.equals(biz.get(field))){
                return true;
            }
        }else {
            if(biz.get(field) != null){
                if(">".equals(validateRule)){
                    if(Optional.of((BigDecimal)biz.get(field)).orElse(BigDecimal.ZERO).compareTo(new BigDecimal(value)) > 0){
                        return true;
                    }
                }else if(">=".equals(validateRule)){
                    if(Optional.of((BigDecimal)biz.get(field)).orElse(BigDecimal.ZERO).compareTo(new BigDecimal(value)) >= 0){
                        return true;
                    }
                }else if("<".equals(validateRule)){
                    if(Optional.of((BigDecimal)biz.get(field)).orElse(BigDecimal.ZERO).compareTo(new BigDecimal(value)) < 0){
                        return true;
                    }
                }else if("<=".equals(validateRule)){
                    if(Optional.of((BigDecimal)biz.get(field)).orElse(BigDecimal.ZERO).compareTo(new BigDecimal(value)) <= 0){
                        return true;
                    }
                }else if("=".equals(validateRule)){
                    if(Optional.of((BigDecimal)biz.get(field)).orElse(BigDecimal.ZERO).compareTo(new BigDecimal(value)) == 0){
                        return true;
                    }
                }
            }
        }
        return false;
    }
    //子表规则校验
    private boolean  judgeBudgetSubject(BizObjectModel biz, String subject, String field, String value, boolean isText, String validateRul){
        List<BizObjectModel> bbList = (List<BizObjectModel>) biz.get(subject);
        boolean relevanceForm1589443509015 = bbList.stream().anyMatch(obj -> {
            return getMatchResult(field, value, isText, obj, validateRul);
        });

        return relevanceForm1589443509015;
    }

    /**
     *  是否所属部门
     * @param routeUnitList
     * @param creater
     * @return
     */
    private boolean unitContainUnit(List<SelectionValue> routeUnitList,SelectionValue creater) {

        UserModel userModel = super.getOrganizationFacade().getUserById(creater.getId());

        // 获取发起人上级部门集合
        List<DepartmentModel> parentDepartments = super.getOrganizationFacade().getParentDepartments(userModel.getDepartmentId());
        if (log.isDebugEnabled()) {
            log.debug("发起人上级部门ids:{}",
                    StringUtils.join(parentDepartments.stream().map(DepartmentModel::getId).collect(Collectors.toList()),","));
        }

        for (SelectionValue obj: routeUnitList ) {
            UnitType type = obj.getType();
            // 申请人所属组织 是 用户
            if (type == UnitType.USER) {
                if (obj.getId() != null && obj.getId().equals(creater.getId())) {
                    log.info("发起人 是  申请人所属组织指定用户");
                    return true;
                }
            }else if(type == UnitType.DEPARTMENT){
                // 申请人所属组织 是 部门
                boolean anyMatch = parentDepartments.stream().anyMatch(dept -> {
                    return  dept.getId().equals(obj.getId());
                });

                log.info("SelectionValue is dept ,deptId ={} , anyMatch = {}", obj.getId(), anyMatch);

                if (anyMatch) {
                    log.info("发起人 是  申请人所属组织用户");
                    return anyMatch;
                }
            }
        }
        log.info("是否所属部门 判断 结束");
        return false;
    }



     static Map<String,Map<String, String>> erpInfo =   new HashMap();
    /**
     *  测试 获取业务服务 接口方法
     * @return
     */
    @RequestMapping("getErpUserInfo")
    public  Object getErpUserInfo(String name){
        Map<String,String > map = Maps.newHashMap();

        if (erpInfo.isEmpty()) {
            String user = "user%s";
            String [] gender = {"男","女"};
            for (int i = 0; i < 20; i++) {
                map = Maps.newHashMap();
                map.put("name", String.format(user, i));
                map.put("age", String.valueOf(18 + i));
                map.put("gender", gender[i%2]);
                erpInfo.put(map.get("name"), map);
            }
        }


        if (name != null) {
          return     erpInfo.get(name);
        }else {
            return new ArrayList(erpInfo.values());
        }


    }

    /**
     *  目前 超过10000 返回 false
     * @return
     */
    @RequestMapping("getYusuan")
    public boolean getYusuan (Integer amount){

        amount = Optional.of(amount).orElse(0);

        return amount>=10000;
    }



    @RequestMapping("getuploadInof")
    public Object getuploadInof(){

        Map<String, Object> map = new HashMap<>();

        map.put("fpCode","DDKF00001");
        map.put("fpNumber","HDSFLKJ-KFLDS-123");
        map.put("fpAmount",3000);



        return  super.getOkResponseResult(map,"上传成功");

    }


}
